package com.doubleblacktech.datamanager
{
	import flash.data.SQLConnection;
	import flash.data.SQLResult;
	import flash.events.SQLErrorEvent;
	import flash.events.SQLEvent;
	import flash.filesystem.File;
	
	import mx.collections.ArrayCollection;
	import mx.controls.Alert;
	
	[Event(name="queryCompleted", type="com.doubleblacktech.datamanager.fxaQueryEvent")]
	
	[Bindable]
	public class FxAConnectionManager extends SQLConnection {
		private var sqlParams:Object;
		private var sqlStmt:FxASqlStatement;

		private var sqlConnections:Array = null;
		private var conn:SQLConnection;
				
		private static var _sqlText:String = "";
		private static var _dbPath:File = null;
		private static var _dbSource:String = "";
		
		private var _dataResults:ArrayCollection;
		
		private static var _instance:FxAConnectionManager;
		
		public function FxAConnectionManager(enforcer:SingletonEnforcer) {
		}
		
		public static function getInstance():FxAConnectionManager {
			if(FxAConnectionManager._instance == null) {
				FxAConnectionManager._instance = new FxAConnectionManager(new SingletonEnforcer());
			}
			
			return FxAConnectionManager._instance;
		}
		
		public function execute(mySqlStmt:FxASqlStatement, params:Object = null):void {
			sqlStmt = mySqlStmt;
			sqlParams = params;
			
			getParameters();
			
			_sqlText = sqlStmt.text;
			
			if(!this.connected) {
				makeAsyncConnection();
			} else {
				executeSQLStmt()
			}
		}

		private function makeAsyncConnection():void {
			this.addEventListener(SQLEvent.OPEN, openSuccess);
			this.addEventListener(SQLErrorEvent.ERROR, errorHandler);
			
			var dbFile:File = dbPath.resolvePath(dbSource+".db");
				
			this.open(dbFile, false);
		}
		
		private function getParameters():void {
			if(sqlParams != null){
				for (var i:String in sqlParams) {
					sqlStmt.parameters[":"+i] = sqlParams[i];
                }
			} else {
				sqlStmt.clearParameters();
			}
		}
		
		private function executeSQLStmt():void {
			sqlStmt.addEventListener(SQLEvent.RESULT, sqlStmtResult);
			sqlStmt.addEventListener(SQLErrorEvent.ERROR, sqlStmtError);
			
			sqlStmt.sqlConnection = this;
			
			sqlStmt.text = _sqlText;
			
			sqlStmt.execute();
		}
		
		//**************************************************************
		// Event Handlers
		//**************************************************************
		private function openSuccess(event:SQLEvent):void {
			this.removeEventListener(SQLEvent.OPEN, openSuccess);
			this.removeEventListener(SQLErrorEvent.ERROR, errorHandler);

			executeSQLStmt();
		}
			
		private function errorHandler(event:SQLErrorEvent):void {
			mx.controls.Alert.show(event.error.message, "fxa Error");
		}
		
		private function sqlStmtResult(event:SQLEvent):void {
			sqlStmt.removeEventListener(SQLEvent.RESULT, sqlStmtResult);
			sqlStmt.removeEventListener(SQLErrorEvent.ERROR, sqlStmtError);
				
			var result:SQLResult = sqlStmt.getResult();
				
			//sqlStmt.addEventListener(fxaQueryEvent.SQLEXECEVENT, dispatchQueryCompleted);
			
			sqlStmt.setSqlStmtResult(result);
			
			var sqlExecEvent:fxaQueryEvent = new fxaQueryEvent(fxaQueryEvent.QUERY_COMPLETED);
			dispatchEvent(sqlExecEvent);
		}
			
		private function dispatchQueryCompleted(event:fxaQueryEvent):void {
			sqlStmt.removeEventListener(fxaQueryEvent.QUERY_COMPLETED, dispatchQueryCompleted);
			
			var sqlExecEvent:fxaQueryEvent = new fxaQueryEvent(fxaQueryEvent.QUERY_COMPLETED);

			dispatchEvent(sqlExecEvent);
		}
		
		private function sqlStmtError(event:SQLErrorEvent):void {
			sqlStmt.removeEventListener(SQLEvent.RESULT, sqlStmtResult);
			sqlStmt.removeEventListener(SQLErrorEvent.ERROR, sqlStmtError);
				
			mx.controls.Alert.show(event.error.message, "fxa Error");
		}
		
		//**************************************************************
		// Getters and Setters
		//**************************************************************
		public function get dbPath():File {
			return _dbPath;
		}
		
		public function set dbPath(value:File):void {
			_dbPath = value;
		}
		
		public function get dbSource():String {
			return _dbSource;
		}
		
		public function set dbSource(value:String):void {
			_dbSource = value;
		}
		
		public function get dataResults():ArrayCollection {
			return _dataResults;
		}
		
		public function set dataResults(value:ArrayCollection):void {
			_dataResults = value;
		}
		
		public function get sqlText():String {
			return _sqlText;
		}
		
		public function set sqlText(value:String):void {
			_sqlText = value;
		}
    	// END: Getters and Setters ***********************************
	}
}

class SingletonEnforcer {}